""" -*- mode: python; coding: utf-8; -*-

    Copyright 2008 Asier Aguirre <asier.aguirre@gmail.com>
    This file is part of Intromit.

    Intromit is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Intromit is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Intromit.  If not, see <http://www.gnu.org/licenses/>.
"""

import sys, pickle, python_config, pyintromit, unittest, python_runner
pyintromit.load("intromit/test/.libs/libpython_doc.so")
import libpython_doc


class test_6_doc(unittest.TestCase):

    def assertExpression(self, exception, expression):
        try:
            exec(expression)
            self.fail("Expression did not failed: "+expression)
        except exception:
            pass

    def test_01(self):
        "Test documentation in detail"
        doc1=libpython_doc.docum1()
        doc2=libpython_doc.docum2()
        doc3=libpython_doc.docum3()
        self.doc4=libpython_doc.docum4()

        self.assertEqual(doc1.__doc__, "doc test class")
        self.assertEqual(doc2.__doc__, None)
        self.assertEqual(doc3.__doc__, "extrange comment\nmore here")
        self.assertEqual(doc1.docum1.__doc__, "constructor doc")
        self.assertEqual(doc2.docum2.__doc__, "second ctor")
        self.assertEqual(doc3.docum3.__doc__, "hello\n     how are you")
        self.assertEqual(self.doc4.docum4.__doc__, "comment more comment")
        self.assertEqual(doc1.docum_fun1.__doc__, None)
        self.assertEqual(doc2.docum_fun2.__doc__, "docum_fun2")
        self.assertEqual(doc3.docum_fun3.__doc__, "docum_fun3")
        self.assertEqual(self.doc4.docum4.__doc__, "comment more comment")
        self.assertEqual(libpython_doc._docum4.member2.__doc__, "i suppose this is member2")
        self.assertEqual(libpython_doc._docum4.member5.__doc__, "comment on member5")
        self.assertEqual(libpython_doc._docum4.member6.__doc__, "comment on member6\ncontinue")
        self.assertEqual(libpython_doc._docum4.with6.__doc__, "comment on member6\ncontinue")
        self.assertEqual(libpython_doc._docum4.member8.__doc__, "Doxygen compatibility")

    def test_02(self):
        "Selection attributes"
        self.doc4=libpython_doc.docum4()
        self.doc5=libpython_doc.docum5()

        self.doc4.member2
        self.doc4.with2
        self.doc4.member5
        self.doc4.member6
        self.doc4.with6
        self.doc4.member8
        self.assertExpression(AttributeError, "self.doc4.member1")
        self.assertExpression(AttributeError, "self.doc4.with1")
        self.assertExpression(AttributeError, "self.doc4.member3")
        self.assertExpression(AttributeError, "self.doc4.member4")
        self.assertExpression(AttributeError, "self.doc4.with4")
        self.assertExpression(AttributeError, "self.doc4.member7")
        self.assertExpression(AttributeError, "self.doc4.with7")
        self.doc4.selected()
        self.doc4.method2()
        self.doc4.method3()
        self.assertExpression(AttributeError, "self.doc4.not_selected()")
        self.assertExpression(AttributeError, "self.doc4.method1()")
        self.assertExpression(AttributeError, "self.doc4.method4()")
        self.doc5.member1
        self.doc5.member4
        self.doc5.member5
        self.doc5.member8
        self.doc5.with4
        self.assertExpression(AttributeError, "self.doc5.member2")
        self.assertExpression(AttributeError, "self.doc5.member3")
        self.assertExpression(AttributeError, "self.doc5.member6")
        self.assertExpression(AttributeError, "self.doc5.member7")
        self.assertExpression(AttributeError, "self.doc5.with6")

    def test_03(self):
        "Read only attribute: ro and read_only"
        self.doc4=libpython_doc.docum4()
        self.assertExpression(AttributeError, "self.doc4.member2=10")
        self.assertExpression(AttributeError, "self.doc4.with2=11")
        self.assertExpression(AttributeError, "self.doc4.member5=12")
        self.doc4.member6=13;

    def test_04(self):
        "Attribute negations: in attribute order"
        self.doc4=libpython_doc.docum4()
        self.doc4.member9
        self.doc4.member10
        self.doc4.member9=14;
        self.assertExpression(AttributeError, "self.doc4.member10=15")

    def test_05(self):
        "Attribute negations: in several attributes"
        self.doc4=libpython_doc.docum4()
        self.doc4.member11
        self.doc4.member12
        self.doc4.member11=16.0
        self.assertExpression(AttributeError, "self.doc4.member12=17.0")

    def test_06(self):
        "Attribute negations: hierarchical"
        self.doc4=libpython_doc.docum4()
        self.doc4.member13
        self.doc4.member14
        self.doc4.member15
        self.doc4.member16
        self.assertExpression(AttributeError, "self.doc4.member13=18")
        self.doc4.member14=True
        self.doc4.member15=20.0
        self.assertExpression(AttributeError, "self.doc4.member16=21.0")
        self.assertExpression(AttributeError, "self.doc4.post5")

    def test_07(self):
        "Class not selected"
        self.assertExpression(AttributeError, "doc6=libpython_doc.docum6()")

    def test_08(self):
        "Get C/C++ class attributes in python"
        self.doc4=libpython_doc.docum4()
        list=self.doc4.__getmdattribute__()
        self.assert_("priority(\"high\")" in list)
        self.assert_("abstract" in list)

    def test_09(self):
        "Get C/C++ member attributes in python"
        self.doc4=libpython_doc.docum4()
        list=self.doc4.__getmdattribute__("member2")
        self.assert_("do_not_serialize(\"by means of python\")" in list)
        self.assert_("ro" in list)
        self.assert_("select" in list)
        self.assert_("so_on" in list)
        list2=self.doc4.__getmdattribute__("with2")
        self.assertEqual(list, list2)
        list=self.doc4.__getmdattribute__("member5")
        self.assert_("emacs_rlz" in list)
        self.assert_("read_only" in list)
        self.assert_("select" in list)
        list=self.doc4.__getmdattribute__("member16")
        self.assert_("ro" in list)

    def test_10(self):
        "Offline metadata attributes"
        self.doc7=libpython_doc.docum7()
        list=self.doc7.__getmdattribute__()
        self.assert_("priority(6)" in list)
        self.assert_("other_attr" in list)
        list=self.doc7.__getmdattribute__("member1")
        self.assert_("ro" in list)
        self.assert_("other(\"#\")" in list)
        list=self.doc7.__getmdattribute__("docum7")
        self.assert_("ctor" in list)

    def test_11(self):
        "Line, block and offline(multiple) combinations"
        self.doc7=libpython_doc.docum7()
        list=self.doc7.__getmdattribute__("member2")
        self.assert_("line1" in list)
        self.assert_("off1" in list)
        list=self.doc7.__getmdattribute__("member3")
        self.assert_("block" in list)
        self.assert_("off2" in list)
        list=self.doc7.__getmdattribute__("member4")
        self.assert_("line2" in list)
        self.assert_("block" in list)
        self.assert_("off3" in list)
        self.assert_("test_colon" in list)
        self.assert_("plus" in list)

    def test_12(self):
        "Line, block and offline priorities"
        self.doc7=libpython_doc.docum7()
        self.doc7.member5=123;
        self.doc7.member6=123;
        self.assertExpression(AttributeError, "self.doc7.member7=123")
        self.assertExpression(AttributeError, "self.doc7.member8")

    def test_13(self):
	"Read-only attribute only for user"
        self.doc7=libpython_doc.docum7()
        self.assertExpression(AttributeError, "self.doc7.member7=123") # not writable
        self.doc7.__setstate__({"member7":9876})
        self.assertEqual(self.doc7.member7, 9876) # written

    def test_14(self):
        "Metadata grouping in offline attribute spec"
        self.doc7=libpython_doc.docum7()
        for i in range(10):
            list=self.doc7.__getmdattribute__("group"+str(i))
            self.assert_("group_of_float(10)" in list)
            self.assert_("more" in list)
            self.assert_("attributes" in list)
            self.assert_("for" in list)
            self.assert_("group" in list)

    def test_15(self):
        "Matching with attributes: refcnt"
        self.doc7=libpython_doc.docum7()
        self.assert_(self.doc7.__debug_internal__()[2]>0)

    def test_16(self):
        "Attributes prepickle and postunpickle"
        doc8=libpython_doc.docum8()
        self.assertEqual(doc8.member1, 0)
        doc8.member1=98765
        doc8.set_member2(12345)
        self.assertEqual(doc8.get_member2(), 12345)
        str=pickle.dumps(doc8)
        doc8=pickle.loads(str)
        self.assertEqual(doc8.member1, 12345)
        self.assertEqual(doc8.get_member2(), 12345)

    def test_17(self):
        "Attribute nopickle"
        doc8=libpython_doc.docum8()
        self.assertEqual(doc8.member3, 99)
        self.assert_("member1" in doc8.__getstate__().keys())
        self.assert_("member3" not in doc8.__getstate__().keys())
        doc8.member3=101
        self.assertEqual(doc8.member3, 101)
        obj=pickle.loads(pickle.dumps(doc8))
        self.assertEqual(obj.member3, 99)

    def test_18(self):
        "Attribute private in members"
        doc8=libpython_doc.docum8()
        self.assert_("member4" not in dir(doc8))
        self.assert_("_member4" in dir(doc8))
        self.assertEqual(doc8._member4, 44)
        doc8._member4=55
        self.assertEqual(doc8._member4, 55)

    def test_19(self):
        "Attribute private in methods"
        doc8=libpython_doc.docum8()
        self.assert_("test_private" not in dir(doc8))
        self.assert_("_test_private" in dir(doc8))
        self.assertEqual(doc8._test_private(3.5), 8)


if __name__ == '__main__':

    suite = unittest.TestLoader().loadTestsFromTestCase(test_6_doc)
    result=python_runner.BasicTestRunner(iterations=len(sys.argv)>1 and sys.argv[1] or 1,
	stream=len(sys.argv)>2 and open(sys.argv[2], "w") or sys.stderr).run(suite)
    sys.exit(not result.wasSuccessful())
